package com.talkweb.osmharmony.tileprovider.modules;

import com.talkweb.osmharmony.api.IMapView;
import com.talkweb.osmharmony.tileprovider.tilesource.ITileSource;
import com.talkweb.osmharmony.util.Log;
import com.talkweb.osmharmony.util.MapTileIndex;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.RdbPredicates;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;
import ohos.data.resultset.ResultSet;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.Set;

/**
 * supports raster imagery in the MBTiles 1.1 spec
 * https://sourceforge.net/p/mobac/code/HEAD/tree/trunk/MOBAC/src/main/java/mobac/program/atlascreators/MBTiles.java
 * https://github.com/mapbox/mbtiles-spec/tree/master/1.1
 *
 * @author neilboyd circa 2011
 */
public class MBTilesFileArchive implements IArchiveFile {

    private RdbStore mDatabase;

    public MBTilesFileArchive() {
    }

    //	TABLE tiles (zoom_level INTEGER, tile_column INTEGER, tile_row INTEGER, tile_data BLOB);
    public final static String TABLE_TILES = "tiles";
    public final static String COL_TILES_ZOOM_LEVEL = "zoom_level";
    public final static String COL_TILES_TILE_COLUMN = "tile_column";
    public final static String COL_TILES_TILE_ROW = "tile_row";
    public final static String COL_TILES_TILE_DATA = "tile_data";

    private MBTilesFileArchive(final RdbStore pDatabase) {
        mDatabase = pDatabase;
    }

//    public static MBTilesFileArchive getDatabaseFileArchive(final File pFile) throws SQLiteException {
//        return new MBTilesFileArchive(
//                SQLiteDatabase.openDatabase(
//                        pFile.getAbsolutePath(),
//                        null,
//                        SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY));
//    }

    @Override
    public void init(File pFile) throws Exception {
        StoreConfig config = StoreConfig.newDefaultConfig(pFile.getAbsolutePath());
        //TODO 此处后续需要增加Context实例
        DatabaseHelper helper = new DatabaseHelper(null);
        mDatabase = helper.getRdbStore(config, 1, null, null);
    }

    @Override
    public InputStream getInputStream(final ITileSource pTileSource, final long pMapTileIndex) {
        try {
            InputStream ret = null;
            final String[] tile = {COL_TILES_TILE_DATA};
            final int offset = MapTileIndex.getZoom(pMapTileIndex) - MapTileIndex.getY(pMapTileIndex) - 1;

            final ResultSet resultSet = mDatabase.query(new RdbPredicates(TABLE_TILES)
                    .equalTo("tile_column", Integer.toString(MapTileIndex.getX(pMapTileIndex))).and()
                    .equalTo("tile_row", Double.toString(Math.pow(2, offset))).and()
                    .equalTo("zoom_level", Integer.toString(MapTileIndex.getZoom(pMapTileIndex))), tile);

            if (resultSet.getRowCount() != 0) {
                resultSet.goToFirstRow();
                ret = new ByteArrayInputStream(resultSet.getBlob(0));
            }
            resultSet.close();
            if (ret != null) {
                return ret;
            }
        } catch (final Throwable e) {
            Log.w(IMapView.LOGTAG, "Error getting db stream: " + MapTileIndex.toString(pMapTileIndex), e);
        }

        return null;
    }

    public Set<String> getTileSources() {
        //the MBTiles spec doesn't store source information in it, so we can't return anything
        return Collections.EMPTY_SET;
    }

    @Override
    public void setIgnoreTileSource(boolean pIgnoreTileSource) {

    }

    @Override
    public void close() {
        mDatabase.close();
    }

    @Override
    public String toString() {
        return "DatabaseFileArchive [mDatabase=" + mDatabase.getPath() + "]";
    }

}
